﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Grammar_judge
{
    public partial class Grammar_judge_Form : Form
    {
        public Grammar_judge_Form()
        {
            InitializeComponent();
        }

        private void Judge_button_Click(object sender, EventArgs e)
        {
            string s = textBox1.Text.ToString();
            Grammar g = new Grammar(s);
            int type = g.Judge();
            switch(type)//判断类型
            {
                case -1:
                    textBox2.Text = "该符号串不是文法";
                    break;
                case 0:
                    textBox2.Text = "该符号串是0型文法";
                    break;
                case 1:
                    textBox2.Text = "该符号串是1型文法";
                    break;
                case 2:
                    textBox2.Text = "该符号串是2型文法";
                    break;
                case 3:
                    textBox2.Text = "该符号串是3型文法";
                    break;
                default:
                    break;
            }
        }

        private void Exit_button_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
    public class Grammar
    {
        public int left_len;//文法左段长度
        public int right_len;//文法右段长度
        public string s;//文法字符串
        public Grammar(string s)
        {
            this.s = s;
        }
        public int Judge()
        {
            int type = -1;//返回值，表示文法的类型
            int len = s.Length;
            int flag_isGram = 0;//判断符号串是否为标准格式的文法
            for (int i = 0; i < len; i++)//判断符号串是否为文法
            {
                if (s[i] == ':' && s[i + 1] == ':' && s[i + 2] == '=')
                {
                    flag_isGram = 1;
                    break;
                }
            }
            for (int i = 0; i < len; i++)
            {
                if (s[i] != ':')
                {
                    left_len++;
                }
                else
                {
                    break;
                }
            }
            right_len = len - left_len - 3;
            int flag_LefthasVn = 0;//左部含有非终结符号Vn集合中的字符的标志
            for (int i = 0; i < left_len; i++)//判断左部是否含有非终结符
            {
                if (s[i] >= 'A' && s[i] <= 'Z')
                {
                    flag_LefthasVn = 1;
                    break;
                }
            }
            if (flag_isGram == 0)
            {
                return type;//非文法
            }
            int flag_0type = 1, flag_1type = 1, flag_2type = 1;//各种类型文法的标志
            if (flag_isGram == 1 && left_len <= right_len && left_len >= 1 && flag_LefthasVn == 1)
            {
                flag_0type = 0;//非0型文法满足左边长度小于等于右边长度
            }//是文法，但满足1型及以上文法条件，则不是0型文法
            else if (flag_isGram == 1 && len >= 5 && flag_LefthasVn == 1)
            {
                type = 0;//0型文法
            }
            if (flag_0type == 0)//若不是0型文法，判断是不是1型文法
            {
                if (left_len == 1 && (s[0] >= 'A' && s[0] <= 'Z'))  //非0型、1型文法情况,2型文法:A->β
                {
                    flag_1type = 0;
                }//不是0型，满足二型及以上条件，则不是1型文法
                else if (left_len >= 1 && right_len >= 1)
                {
                    type = 1;
                }
            }
            if (flag_1type == 0)//若不是1型文法，判断是不是2型文法
            {
                if (left_len == 1 && right_len == 1 && (s[0] >= 'A' && s[0] <= 'Z') && ((s[4] >= 'a' && s[4] <= 'z') || (s[4] >= '0' && s[4] <= '9') || s[4] == '+' || s[4] == '-' || s[4] == '*' || s[4] == '/' || s[4] == '%' || s[4] == '(' || s[4] == ')' || s[4] == '[' || s[4] == ']' || s[4] == '{' || s[4] == '}'))//三型文法 A::=α类型
                {
                    flag_2type = 0;
                }
                else if (left_len == 1 && right_len == 2 && (s[0] >= 'A' && s[0] <= 'Z') && ((s[4] >= 'a' && s[4] <= 'z') || (s[4] >= '0' && s[4] <= '9') || s[4] == '+' || s[4] == '-' || s[4] == '*' || s[4] == '/' || s[4] == '%' || s[4] == '(' || s[4] == ')' || s[4] == '[' || s[4] == ']' || s[4] == '{' || s[4] == '}') && (s[5] >= 'A' && s[5] <= 'Z'))//三型文法 A::=αB类型
                {
                    flag_2type = 0;
                }
                else if (left_len == 1 && right_len == 2 && (s[0] >= 'A' && s[0] <= 'Z') && ((s[5] >= 'a' && s[5] <= 'z') || (s[5] >= '0' && s[5] <= '9') || s[5] == '+' || s[5] == '-' || s[5] == '*' || s[5] == '/' || s[5] == '%' || s[5] == '(' || s[5] == ')' || s[5] == '[' || s[5] == ']' || s[5] == '{' || s[5] == '}') && (s[4] >= 'A' && s[4] <= 'Z'))//三型文法 A::=Bα类型
                {
                    flag_2type = 0;
                }//不是1型，满足3型条件，则不是2型
                else
                {
                    type = 2;
                }
            }
            if (flag_2type == 0)//不是2型文法，则是3型文法
            {
                type = 3;
            }
            return type;
        }
    }
}
